package UserInterface;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import Main.Main;

@SuppressWarnings("serial")
/**
 * It is responsible for the other screens and links on that screens.
 */
public class GUIManager extends JFrame implements KeyListener
{
	public static ImageManager images;
	private Screen mainScreen;
	private GameScreen gameScreen;
	private Screen optionsScreen;
	private Screen howtoplayScreen;
	private Screen creditsScreen;
	private HighScoreScreen scoreScreen;
	private Screen activeScreen;
	private boolean gameMode;
	

	/**
	 * Initializes the screen of the game and prepares every link on the screens.
	 */
	public GUIManager()
	{
		gameMode = false;
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setFocusable(true);
		this.setResizable(false);
		this.addKeyListener(this);
		images = new ImageManager();
//------Define Main Screen-----------------------------------
		mainScreen = new Screen(images.mainScreen,null);


		ArrayList<Link> mainScreenLinks = new ArrayList<Link>();
		Link startGame = new Link(213, 129, 218, 38, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("gameScreen");
				Main.mygame.start();
			}
		}, false);
		Link options = new Link(241, 194, 153, 41, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("optionsScreen");
			}
		}, false);
		Link howToPlay = new Link(200, 264, 229, 45, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("howtoplayScreen");
			}
		}, false);
		Link highScores = new Link(201, 325, 231, 44, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("scoreScreen");
				Main.GUI.getScoreScreen().showHighScore();
			}
		}, false);
		
		Link credits = new Link(235, 384, 150, 37, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("creditsScreen");
			}
		}, false);
		
		Link exit = new Link(266, 434, 82, 37, new CallBackFunction(){
			public void run(){
				System.exit(1);
			}
		}, false);
		mainScreenLinks.add(startGame);
		mainScreenLinks.add(options);
		mainScreenLinks.add(howToPlay);
		mainScreenLinks.add(credits);
		mainScreenLinks.add(highScores);
		mainScreenLinks.add(exit);
		mainScreen.setLinks(mainScreenLinks);
//------Define Main Screen END -----------------------------------

//------Define Option Screen-----------------------------------
		optionsScreen = new Screen(images.optionsScreen, null);
		ArrayList<Link> optionsLink = new ArrayList<Link>();
		Link changeColor = new Link(230, 188, 304, 37, new CallBackFunction(){
			public void run(){
				Main.mygame.getBoat().setColor(!Main.mygame.getBoat().getColor());
			}
		}, false);
		Link soundOn = new Link(394, 282, 63, 34, new CallBackFunction(){
			public void run(){
				Main.GUI.optionsScreen.getLinks().get(1).setAlwaysActive(true);
				Main.GUI.optionsScreen.getLinks().get(2).setAlwaysActive(false);
				Main.mygame.setMusicOn();
			}
		}, false);
		Link soundOff = new Link(475, 280, 89, 37, new CallBackFunction(){
			public void run(){
				Main.GUI.optionsScreen.getLinks().get(2).setAlwaysActive(true);
				Main.GUI.optionsScreen.getLinks().get(1).setAlwaysActive(false);
				Main.mygame.setMusicOff();
			}
		}, false);
		Link easy = new Link(225, 344, 128, 39, new CallBackFunction(){
			public void run(){
				Main.GUI.optionsScreen.getLinks().get(3).setAlwaysActive(true);
				Main.GUI.optionsScreen.getLinks().get(4).setAlwaysActive(false);
				Main.mygame.setGameSpeed(120);
			}
		}, false);
		Link hard = new Link(447, 344, 128, 39, new CallBackFunction(){
			public void run(){
				Main.GUI.optionsScreen.getLinks().get(4).setAlwaysActive(true);
				Main.GUI.optionsScreen.getLinks().get(3).setAlwaysActive(false);
				Main.mygame.setGameSpeed(60);
			}
		}, false);
		Link back = new Link(93, 440, 124, 34, new CallBackFunction(){
			public void run(){
				Main.GUI.setActiveScreen("mainScreen");
			}
		}, false);
		optionsLink.add(changeColor);
		optionsLink.add(soundOn);
		optionsLink.add(soundOff);
		optionsLink.add(easy);
		optionsLink.add(hard);
		optionsLink.add(back);
		optionsScreen.setLinks(optionsLink);
//------Define Option Screen END-----------------------------------
		

//------Define Game Screen-----------------------------------
		gameScreen = new GameScreen(images.getRiverBackgroundImage());
//------Define Game Screen END-----------------------------------

//------Define Credits Screen-----------------------------------
		ArrayList<Link> creditsLink = new ArrayList<Link>();
		creditsScreen = new Screen(images.getCreditsScreen(),null);
		creditsLink.add(back);
		creditsScreen.setLinks(creditsLink);
//------Define Option Screen END-----------------------------------

//------Define howtoplayScreen Screen-----------------------------------
		ArrayList<Link> howtoplayLink = new ArrayList<Link>();
		howtoplayScreen = new Screen(images.getHowToPlayScreen(),null);
		howtoplayLink.add(back);
		howtoplayScreen.setLinks(howtoplayLink);
//------Define howtoplayScreen Screen END-----------------------------------

//------Define HighScoreScreen Screen-----------------------------------
		ArrayList<Link> scoreLink = new ArrayList<Link>();
		scoreScreen = new HighScoreScreen(images.getHighScoreScreen(),null);
		scoreLink.add(back);
		scoreScreen.setLinks(scoreLink);
//------Define HighScoreScreen Screen END---
		
		
		
		activeScreen = mainScreen;
		
		this.setSize(activeScreen.getBackgroundImage().getIconWidth(), activeScreen.getBackgroundImage().getIconHeight());
		
		this.add(activeScreen);
		
		this.setVisible(true);
	}


	/**
	 * Changes and renders the given screen
	 * @param screen is the given screen name which will be rendered
	 */
	public void setActiveScreen(String screen)
	{
			if( screen.equals("mainScreen"))
			{
				activeScreen = Main.GUI.mainScreen;
			}
			if( screen.equals("optionsScreen"))
			{
				activeScreen = Main.GUI.optionsScreen;
			}
			if( screen.equals("howtoplayScreen"))
			{
				activeScreen = Main.GUI.howtoplayScreen;
			}
			if( screen.equals("creditsScreen"))
			{
				activeScreen = Main.GUI.creditsScreen;
			}
	
			if( screen.equals("scoreScreen"))
			{
				activeScreen = Main.GUI.scoreScreen;
			}
			
			if (activeScreen.getBackgroundImage()!=null)
			{
				this.setSize(activeScreen.getBackgroundImage().getIconWidth(), activeScreen.getBackgroundImage().getIconHeight());
			}
			
			
			if(!screen.equals("gameScreen") &&  !screen.equals("scoreScreen"))
			{
				this.getContentPane().removeAll();
				this.getContentPane().add(activeScreen);
				this.validate();
			}
			
			if( screen.equals("gameScreen"))
			{

				this.getContentPane().removeAll();
				this.getContentPane().add(gameScreen);
				this.gameMode = true;
				this.validate();
			}
			
			
			if( screen.equals("scoreScreen"))
			{
				this.getContentPane().removeAll();
				this.getContentPane().add(scoreScreen);
				this.validate();
			}
			
			this.repaint();
			
		
	}

	public ImageManager getImages() {
		return images;
	}

	public void setImages(ImageManager images) {
		this.images = images;
	}

	public Screen getMainScreen() {
		return mainScreen;
	}

	public void setMainScreen(Screen mainScreen) {
		this.mainScreen = mainScreen;
	}

	public GameScreen getGameScreen() {
		return gameScreen;
	}

	public void setGameScreen(GameScreen gameScreen) {
		this.gameScreen = gameScreen;
	}

	public Screen getOptionsScreen() {
		return optionsScreen;
	}

	public void setOptionsScreen(Screen optionsScreen) {
		this.optionsScreen = optionsScreen;
	}

	public Screen getHowtoplayScreen() {
		return howtoplayScreen;
	}

	public void setHowtoplayScreen(Screen howtoplayScreen) {
		this.howtoplayScreen = howtoplayScreen;
	}

	public Screen getCreditsScreen() {
		return creditsScreen;
	}

	public void setCreditsScreen(Screen creditsScreen) {
		this.creditsScreen = creditsScreen;
	}

	public HighScoreScreen getScoreScreen() {
		return scoreScreen;
	}

	public void setScoreScreen(HighScoreScreen scoreScreen) {
		this.scoreScreen = scoreScreen;
	}

	public Screen getActiveScreen() {
		return activeScreen;
	}

	public void setActiveScreen(Screen activeScreen) {
		this.activeScreen = activeScreen;
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if( this.gameMode)
		{
			switch(e.getKeyCode()){
			case 38:
				Main.mygame.getBoat().setForward(true);
				break;
			case 39:
				Main.mygame.getBoat().setRight(true);
				break;
			case 40:
				Main.mygame.getBoat().setBack(true);
				break;
			case 37:
				Main.mygame.getBoat().setLeft(true);
				break;
			}
		
		}
	}

	public void keyReleased(KeyEvent e) {
			switch(e.getKeyCode()){
			case 38:
				Main.mygame.getBoat().setForward(false);
				break;
			case 39:
				Main.mygame.getBoat().setRight(false);
				break;
			case 40:
				Main.mygame.getBoat().setBack(false);
				break;
			case 37:
				Main.mygame.getBoat().setLeft(false);
				break;
			}
			
			if (e.getKeyCode()>37 && e.getKeyCode()<41)
			{
				Main.mygame.setKeyPressCounter(Main.mygame.getKeyPressCounter()+1);
				Main.mygame.checkSpeed();
			}
	}


	/**
	 * If some key typed during the game it pauses the game
	 */
	public void keyTyped(KeyEvent e) {
		if( Main.GUI.gameMode){
			if( !Main.mygame.isGameOver()){
				if( !Main.mygame.isPaused()){
					Main.mygame.getTimer().stop();
					Main.mygame.setPaused(true);
				}
				else{
					Main.mygame.getTimer().start();
					Main.mygame.setPaused(false);
				}
			}
		}
	}
	

	/**
	 * Draws a border on option screen by checking whether the settings are active.
	 * @param isMusicOn is the condition of the music play
	 * @param gameSpeed is determines whether the game is on hard or easy mode
	 */
	public void getOptionsForVisual(boolean isMusicOn, int gameSpeed){
		if( isMusicOn)
			this.optionsScreen.getLinks().get(1).setAlwaysActive(true);
		else
			this.optionsScreen.getLinks().get(2).setAlwaysActive(true);
		if( gameSpeed == 60)
			this.optionsScreen.getLinks().get(4).setAlwaysActive(true);
		else
			this.optionsScreen.getLinks().get(3).setAlwaysActive(true);
			
	}


	public boolean isGameMode() {
		return gameMode;
	}


	public void setGameMode(boolean gameMode) {
		this.gameMode = gameMode;
	}
	
}